//
//  NSString+YHCommon.h
//  YHBaseProject
//
//  Created by 刘宇航 on 2018/5/1.
//  Copyright © 2018 lyh. All rights reserved.
//


#import "NSString+XMCommon.h"
//#import "GTMBase64.h"
#include <CommonCrypto/CommonDigest.h>


@implementation NSString (XMCommon)

+ (NSString *)xm_stringFromDitance:(NSString *)distance {
    NSString *distanceStr = @"";
    if (distance.intValue >= 1000) {
        if (distance.intValue % 1000 == 0) { //1000的整数倍,去掉小数
            distanceStr = [NSString stringWithFormat:@"%dkm", distance.intValue / 1000];
        } else {
            distanceStr = [NSString stringWithFormat:@"%0.1fkm", distance.intValue / 1000.0];
        }
    } else if (distance.intValue == 0) {
        distanceStr = @"";
    } else {
        distanceStr = [NSString stringWithFormat:@"%dm", distance.intValue];
    }
    return [distanceStr stringByReplacingOccurrencesOfString:@".0" withString:@""];
}

+ (NSString *)xm_stringFromPrice:(NSNumber *)price {
    return [NSString stringWithFormat:@"%0.2f", price.intValue / 100.0];
}

+ (NSString *)xm_stringMoneyFromPrice:(NSNumber *)price {
    return [NSString xm_deleteFloatAllZeroWith:[NSString xm_stringFromPrice:price]];
}

// 字符串金额至少保留两位小数位末尾去零
+ (NSString *)xm_deleteFloatAllZeroWith:(NSString *)str {
    if ([str containsString:@"."]) {
        NSArray *arrStr = [str componentsSeparatedByString:@"."];
        NSString *str1 = arrStr.firstObject;
        NSString *str2 = arrStr.lastObject;
        while ([str2 hasSuffix:@"0"]) {
            str2 = [str2 substringToIndex:(str2.length - 1)];
        }
        if (str2.length > 1) {
            return [NSString stringWithFormat:@"%@.%@", str1, str2];
        } else if (str2.length == 1) {
            return [NSString stringWithFormat:@"%@.%@", str1, str2];
        }
        return [NSString stringWithFormat:@"%@", str1];
    }
    return [NSString stringWithFormat:@"%@", str];
}

+ (BOOL)isEmpty:(NSString *)string {
    if (string == nil || string == NULL || [string isEqual:[NSNull null]]) {
        return YES;
    }
    if ([string isKindOfClass:[NSNull class]]) {
        return YES;
    }
    if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) {
        return YES;
    }
    if ([string isEqualToString:@"(null)"]) {
        return YES;
    }
    if (string.length == 0) {
        return YES;
    }
    return NO;
}

#pragma mark------------------------ 正则表达式判断 -----------------------
- (BOOL)isValidateByRegex:(NSString *)regex {
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [pre evaluateWithObject:self];
}

- (BOOL)xm_isUserName {
    NSString *regex = @"(^[A-Za-z0-9]{3,20}$)";
    return [self isValidateByRegex:regex];
}

- (BOOL)xm_isPassword {
    //    NSString *regex = @"(^[A-Za-z0-9]{6,20}$)";
    //以字母开头，只能包含“字母”，“数字”，“下划线”，长度6~16
    NSString *regex = @"^(?![0-9]+$)(?![a-zA-Z]+$)[a-zA-Z0-9]{6,16}";
    return [self isValidateByRegex:regex];
}

- (BOOL)xm_isEmail {
    NSString *regex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    return [self isValidateByRegex:regex];
}

- (BOOL)xm_isUrl {
    NSString *regex = @"http(s)?:\\/\\/([\\w-]+\\.)+[\\w-]+(\\/[\\w- .\\/?%&=]*)?";
    return [self isValidateByRegex:regex];
}

//手机号分服务商
- (BOOL)xm_isMobileNumberClassification {
    /**
     * 手机号码
     * 移动：134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188,1705
     * 联通：130,131,132,152,155,156,185,186,1709
     * 电信：133,1349,153,180,189,1700,173
     */
    NSString *MOBILE = @"^1(3[0-9]|4[57]|5[0-35-9]|6[6]|8[0-9]|9[89]|7[0678])\\d{8}$";
    
    /**
     10         * 中国移动：China Mobile
     11         * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188，1705
     12         */
    NSString *CM = @"(^1(3[4-9]|4[7]|5[0-27-9]|7[8]|8[2-478]|9[8])\\d{8}$)|(^1705\\d{7}$)";
    
    /**
     15         * 中国联通：China Unicom
     16         * 130,131,132,152,155,156,185,186,1709
     17         */
    NSString *CU = @"(^1(3[0-2]|4[5]|5[56]|6[6]|7[6]|8[56])\\d{8}$)|(^1709\\d{7}$)";
    /**
     20         * 中国电信：China Telecom
     21         * 133,1349,153,180,189,1700,173
     22         */
    NSString *CT = @"(^1(33|53|77|99|8[019])\\d{8}$)|(^1700\\d{7}$)";
    /**
     25         * 大陆地区固话及小灵通
     26         * 区号：010,020,021,022,023,024,025,027,028,029
     27         * 号码：七位或八位
     28         */
    //    NSString *PHS = @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
    
    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];
    //    NSPredicate *regextestphs = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", PHS];
    
    return [regextestmobile evaluateWithObject:self] ||
    //    [regextestphs evaluateWithObject:self]      ||
    [regextestct evaluateWithObject:self] ||
    [regextestcu evaluateWithObject:self] ||
    [regextestcm evaluateWithObject:self];
}
//手机号有效性
- (BOOL)xm_isMobileNumber {
    NSString *regex = @"^(0|86|17951)?(13[0-9]|15[012356789]|17[0678]|18[0-9]|14[57])[0-9]{8}$";
    return [self isValidateByRegex:regex];
}

// 身份证号
- (BOOL)xm_isidentityCard {
    NSString *regex = @"^(\\d{14}|\\d{17})(\\d|[xX])$";
    return [self isValidateByRegex:regex];
}
- (BOOL)xm_isNumber {
    NSString *regex = @"^[0-9]*$";
    return [self isValidateByRegex:regex];
}

- (BOOL)xm_isWhitespaceAndNewlines {
    NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    for (NSInteger i = 0; i < self.length; ++i) {
        unichar c = [self characterAtIndex:i];
        if (![whitespace characterIsMember:c]) {
            return NO;
        }
    }
    return YES;
}

//车牌
- (BOOL)xm_isCarNumber {
    //车牌号:湘K-DE829 香港车牌号码:粤Z-J499港
    NSString *carRegex = @"^[\u4e00-\u9fff]{1}[a-zA-Z]{1}[-][a-zA-Z_0-9]{4}[a-zA-Z_0-9_\u4e00-\u9fff]$"; //其中\u4e00-\u9fa5表示unicode编码中汉字已编码部分，\u9fa5-\u9fff是保留部分，将来可能会添加
    return [self isValidateByRegex:carRegex];
}

- (BOOL)xm_isMacAddress {
    NSString *macAddRegex = @"([A-Fa-f\\d]{2}:){5}[A-Fa-f\\d]{2}";
    return [self isValidateByRegex:macAddRegex];
}

- (BOOL)xm_isValidUrl {
    NSString *regex = @"^((http)|(https))+:[^\\s]+\\.[^\\s]*$";
    return [self isValidateByRegex:regex];
}

- (BOOL)xm_isValidChinese {
    NSString *chineseRegex = @"^[\u4e00-\u9fa5]+$";
    return [self isValidateByRegex:chineseRegex];
}

- (BOOL)xm_isValidPostalcode {
    NSString *postalRegex = @"^[0-8]\\d{5}(?!\\d)$";
    return [self isValidateByRegex:postalRegex];
}

- (BOOL)xm_isValidTaxNo {
    NSString *taxNoRegex = @"[0-9]\\d{13}([0-9]|X)$";
    return [self isValidateByRegex:taxNoRegex];
}

#pragma mark - 算法相关
//精确的身份证号码有效性检测
+ (BOOL)xm_accurateVerifyIDCardNumber:(NSString *)value {
    value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    int length = 0;
    if (!value) {
        return NO;
    } else {
        length = (int)value.length;
        
        if (length != 15 && length != 18) {
            return NO;
        }
    }
    // 省份代码
    NSArray *areasArray = @[@"11", @"12", @"13", @"14", @"15", @"21", @"22", @"23", @"31", @"32", @"33", @"34", @"35", @"36", @"37", @"41", @"42", @"43", @"44", @"45", @"46", @"50", @"51", @"52", @"53", @"54", @"61", @"62", @"63", @"64", @"65", @"71", @"81", @"82", @"91"];
    
    NSString *valueStart2 = [value substringToIndex:2];
    BOOL areaFlag = NO;
    for (NSString *areaCode in areasArray) {
        if ([areaCode isEqualToString:valueStart2]) {
            areaFlag = YES;
            break;
        }
    }
    if (!areaFlag) {
        return false;
    }
    
    NSRegularExpression *regularExpression;
    NSUInteger numberofMatch;
    
    int year = 0;
    switch (length) {
        case 15:
            year = [value substringWithRange:NSMakeRange(6, 2)].intValue + 1900;
            
            if (year % 4 == 0 || (year % 100 == 0 && year % 4 == 0)) {
                regularExpression = [[NSRegularExpression alloc] initWithPattern:@"^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$"
                                                                         options:NSRegularExpressionCaseInsensitive
                                                                           error:nil]; //测试出生日期的合法性
            } else {
                regularExpression = [[NSRegularExpression alloc] initWithPattern:@"^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$"
                                                                         options:NSRegularExpressionCaseInsensitive
                                                                           error:nil]; //测试出生日期的合法性
            }
            numberofMatch = [regularExpression numberOfMatchesInString:value
                                                               options:NSMatchingReportProgress
                                                                 range:NSMakeRange(0, value.length)];
            
            if (numberofMatch > 0) {
                return YES;
            } else {
                return NO;
            }
        case 18:
            year = [value substringWithRange:NSMakeRange(6, 4)].intValue;
            if (year % 4 == 0 || (year % 100 == 0 && year % 4 == 0)) {
                regularExpression = [[NSRegularExpression alloc] initWithPattern:@"^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$"
                                                                         options:NSRegularExpressionCaseInsensitive
                                                                           error:nil]; //测试出生日期的合法性
            } else {
                regularExpression = [[NSRegularExpression alloc] initWithPattern:@"^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$"
                                                                         options:NSRegularExpressionCaseInsensitive
                                                                           error:nil]; //测试出生日期的合法性
            }
            numberofMatch = [regularExpression numberOfMatchesInString:value
                                                               options:NSMatchingReportProgress
                                                                 range:NSMakeRange(0, value.length)];
            
            if (numberofMatch > 0) {
                int S = ([value substringWithRange:NSMakeRange(0, 1)].intValue + [value substringWithRange:NSMakeRange(10, 1)].intValue) * 7 + ([value substringWithRange:NSMakeRange(1, 1)].intValue + [value substringWithRange:NSMakeRange(11, 1)].intValue) * 9 + ([value substringWithRange:NSMakeRange(2, 1)].intValue + [value substringWithRange:NSMakeRange(12, 1)].intValue) * 10 + ([value substringWithRange:NSMakeRange(3, 1)].intValue + [value substringWithRange:NSMakeRange(13, 1)].intValue) * 5 + ([value substringWithRange:NSMakeRange(4, 1)].intValue + [value substringWithRange:NSMakeRange(14, 1)].intValue) * 8 + ([value substringWithRange:NSMakeRange(5, 1)].intValue + [value substringWithRange:NSMakeRange(15, 1)].intValue) * 4 + ([value substringWithRange:NSMakeRange(6, 1)].intValue + [value substringWithRange:NSMakeRange(16, 1)].intValue) * 2 + [value substringWithRange:NSMakeRange(7, 1)].intValue * 1 + [value substringWithRange:NSMakeRange(8, 1)].intValue * 6 + [value substringWithRange:NSMakeRange(9, 1)].intValue * 3;
                int Y = S % 11;
                NSString *M = @"F";
                NSString *JYM = @"10X98765432";
                M = [JYM substringWithRange:NSMakeRange(Y, 1)]; // 判断校验位
                NSString *test = [value substringWithRange:NSMakeRange(17, 1)];
                if ([[M lowercaseString] isEqualToString:[test lowercaseString]]) {
                    return YES; // 检测ID的校验位
                } else {
                    return NO;
                }
                
            } else {
                return NO;
            }
        default:
            return NO;
    }
}

/** 银行卡号有效性问题Luhn算法
 *  现行 16 位银联卡现行卡号开头 6 位是 622126～622925 之间的，7 到 15 位是银行自定义的，
 *  可能是发卡分行，发卡网点，发卡序号，第 16 位是校验码。
 *  16 位卡号校验位采用 Luhm 校验方法计算：
 *  1，将未带校验位的 15 位卡号从右依次编号 1 到 15，位于奇数位号上的数字乘以 2
 *  2，将奇位乘积的个十位全部相加，再加上所有偶数位上的数字
 *  3，将加法和加上校验位能被 10 整除。
 */
- (BOOL)xm_bankCardluhmCheck {
    NSString *lastNum = [[self substringFromIndex:(self.length - 1)] copy]; //取出最后一位
    NSString *forwardNum = [[self substringToIndex:(self.length - 1)] copy]; //前15或18位
    
    NSMutableArray *forwardArr = [[NSMutableArray alloc] initWithCapacity:0];
    for (int i = 0; i < forwardNum.length; i++) {
        NSString *subStr = [forwardNum substringWithRange:NSMakeRange(i, 1)];
        [forwardArr addObject:subStr];
    }
    
    NSMutableArray *forwardDescArr = [[NSMutableArray alloc] initWithCapacity:0];
    for (int i = (int)(forwardArr.count - 1); i > -1; i--) { //前15位或者前18位倒序存进数组
        [forwardDescArr addObject:forwardArr[i]];
    }
    
    NSMutableArray *arrOddNum = [[NSMutableArray alloc] initWithCapacity:0]; //奇数位*2的积 < 9
    NSMutableArray *arrOddNum2 = [[NSMutableArray alloc] initWithCapacity:0]; //奇数位*2的积 > 9
    NSMutableArray *arrEvenNum = [[NSMutableArray alloc] initWithCapacity:0]; //偶数位数组
    
    for (int i = 0; i < forwardDescArr.count; i++) {
        NSInteger num = [forwardDescArr[i] intValue];
        if (i % 2) { //偶数位
            [arrEvenNum addObject:[NSNumber numberWithInteger:num]];
        } else { //奇数位
            if (num * 2 < 9) {
                [arrOddNum addObject:[NSNumber numberWithInteger:num * 2]];
            } else {
                NSInteger decadeNum = (num * 2) / 10;
                NSInteger unitNum = (num * 2) % 10;
                [arrOddNum2 addObject:[NSNumber numberWithInteger:unitNum]];
                [arrOddNum2 addObject:[NSNumber numberWithInteger:decadeNum]];
            }
        }
    }
    
    __block NSInteger sumOddNumTotal = 0;
    [arrOddNum enumerateObjectsUsingBlock:^(NSNumber *obj, NSUInteger idx, BOOL *stop) {
        sumOddNumTotal += [obj integerValue];
    }];
    
    __block NSInteger sumOddNum2Total = 0;
    [arrOddNum2 enumerateObjectsUsingBlock:^(NSNumber *obj, NSUInteger idx, BOOL *stop) {
        sumOddNum2Total += [obj integerValue];
    }];
    
    __block NSInteger sumEvenNumTotal = 0;
    [arrEvenNum enumerateObjectsUsingBlock:^(NSNumber *obj, NSUInteger idx, BOOL *stop) {
        sumEvenNumTotal += [obj integerValue];
    }];
    
    NSInteger lastNumber = [lastNum integerValue];
    
    NSInteger luhmTotal = lastNumber + sumEvenNumTotal + sumOddNum2Total + sumOddNumTotal;
    
    return (luhmTotal % 10 == 0) ? YES : NO;
}

- (BOOL)xm_isIPAddress {
    NSString *regex = [NSString stringWithFormat:@"^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$"];
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    BOOL rc = [pre evaluateWithObject:self];
    
    if (rc) {
        NSArray *componds = [self componentsSeparatedByString:@","];
        
        BOOL v = YES;
        for (NSString *s in componds) {
            if (s.integerValue > 255) {
                v = NO;
                break;
            }
        }
        
        return v;
    }
    
    return NO;
}
#pragma mark - Utils
- (NSString *)xm_trim {
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSString *)xm_removeWhiteSpace {
    return [[self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] componentsJoinedByString:@""];
}

- (NSString *)xm_removeNewLine {
    return [[self componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]] componentsJoinedByString:@""];
}

- (NSString *)xm_stringByStrippingHTML {
    return [self stringByReplacingOccurrencesOfString:@"<[^>]+>" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, self.length)];
}

- (NSString *)xm_stringByRemovingScriptsAndStrippingHTML {
    NSMutableString *mString = [self mutableCopy];
    NSError *error;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"<script[^>]*>[\\w\\W]*</script>" options:NSRegularExpressionCaseInsensitive error:&error];
    NSArray *matches = [regex matchesInString:mString options:NSMatchingReportProgress range:NSMakeRange(0, [mString length])];
    for (NSTextCheckingResult *match in [matches reverseObjectEnumerator]) {
        [mString replaceCharactersInRange:match.range withString:@""];
    }
    return [mString xm_stringByStrippingHTML];
}

- (NSString *)xm_capitalize {
    if (self == nil || [self length] == 0) return self;
    return [[self substringToIndex:1].uppercaseString stringByAppendingString:[self substringFromIndex:1]];
}

- (BOOL)xm_startsWith:(NSString *)str {
    return [self xm_startsWith:str Options:NSCaseInsensitiveSearch];
}

- (BOOL)xm_startsWith:(NSString *)str Options:(NSStringCompareOptions)compareOptions {
    return (str != nil) && ([str length] > 0) && ([self length] >= [str length])
    && ([self rangeOfString:str options:compareOptions].location == 0);
}

- (BOOL)xm_endsWith:(NSString *)str {
    return [self xm_endsWith:str Options:NSCaseInsensitiveSearch];
}

- (BOOL)xm_endsWith:(NSString *)str Options:(NSStringCompareOptions)compareOptions {
    return (str != nil) && ([str length] > 0) && ([self length] >= [str length])
    && ([self rangeOfString:str options:(compareOptions | NSBackwardsSearch)].location == ([self length] - [str length]));
}

- (BOOL)xm_containsString:(NSString *)str {
    return [self xm_containsString:str Options:NSCaseInsensitiveSearch];
}

- (BOOL)xm_containsString:(NSString *)str Options:(NSStringCompareOptions)compareOptions {
    return (str != nil) && ([str length] > 0) && ([self length] >= [str length]) && ([self rangeOfString:str options:compareOptions].location != NSNotFound);
}

- (BOOL)xm_equalsString:(NSString *)str {
    return (str != nil) && ([self length] == [str length]) && ([self rangeOfString:str options:NSCaseInsensitiveSearch].location == 0);
}

+ (NSString *)xm_phoneNumFormat:(NSString *)phoneString {
    BOOL flag = NO; //是否是以“1”开头
    if (phoneString && phoneString.length >= 1) {
        NSString *firstStr = [phoneString substringToIndex:1];
        if ([firstStr isEqualToString:@"1"] && [phoneString rangeOfString:@"@"].location == NSNotFound) {
            flag = YES;
        } else {
            flag = NO;
        }
    }
    
    if (flag) {
        phoneString = [phoneString stringByReplacingOccurrencesOfString:@" " withString:@""];
        if (phoneString.length > 3) {
            NSString *a = [[phoneString substringToIndex:3] stringByAppendingString:@" "];
            NSString *b = [phoneString substringFromIndex:3];
            for (NSUInteger i = 0; i + 4 < b.length; i += 4) {
                NSString *c = [[b substringWithRange:NSMakeRange(i, 4)] stringByAppendingString:@" "];
                a = [a stringByAppendingString:c];
            }
            NSUInteger spareLen = (b.length % 4 == 0 ? 4 : b.length % 4);
            NSString *spare = [b substringFromIndex:b.length - spareLen];
            a = [a stringByAppendingString:spare];
            return a;
        }
    }
    
    return phoneString;
}

+ (NSString *)xm_formateBankNum:(NSString *)cardId {
    NSUInteger lenth = cardId.length;
    NSString *str1 = [cardId substringToIndex:4];
    NSString *str2 = [cardId substringFromIndex:lenth - 4];
    NSMutableString *str3 = [[NSMutableString alloc] init];
    for (int i = 0; i < lenth - 8; i++) {
        [str3 appendString:@"*"];
    }
    NSString *str = [NSString stringWithFormat:@"%@%@%@", str1, str3, str2];
    return str;
}


+ (NSString *)xm_stringFormatWithVoiceTime:(NSInteger)time {
    NSDateFormatter *dfm = [[NSDateFormatter alloc] init];
    [dfm setDateFormat:@"mm:ss"];
    
    NSString *str = [dfm stringFromDate:[NSDate dateWithTimeIntervalSince1970:time]];
    
    NSArray *arr = [str componentsSeparatedByString:@":"];
    str = [NSString stringWithFormat:@"%@'%@\"", arr[0], arr[1]];
    return str;
}

+ (NSString *)xm_stringFormatWithVoiceTime1:(NSInteger)time {
    NSDateFormatter *dfm = [[NSDateFormatter alloc] init];
    [dfm setDateFormat:@"mm:ss"];
    return [dfm stringFromDate:[NSDate dateWithTimeIntervalSince1970:time]];
}

+ (NSString *)xm_dateStringWithTime:(NSString *)time {
    NSDate *fromDate = [NSDate dateWithTimeIntervalSince1970:[time doubleValue]];
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *comps = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay)
                                          fromDate:fromDate];
    NSDateComponents *compsNow = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay)
                                             fromDate:[NSDate date]];
    
    NSDateFormatter *dfm = [[NSDateFormatter alloc] init];
    [dfm setAMSymbol:NSLocalizedString(@"AM", nil)];
    [dfm setPMSymbol:NSLocalizedString(@"PM", nil)];
    [dfm setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"zh"]];
    [dfm setDateFormat:@"yyyy:MM:dd:hh:mm:a"];
    NSString *dateStrr = [dfm stringFromDate:fromDate];
    NSArray *dateArr = [dateStrr componentsSeparatedByString:@":"];
    
    NSString *yyyy = [dateArr objectAtIndex:0];
    NSString *MM = [dateArr objectAtIndex:1];
    NSString *dd = [dateArr objectAtIndex:2];
    NSString *hh = [dateArr objectAtIndex:3];
    NSString *mm = [dateArr objectAtIndex:4];
    NSString *ampm = [dateArr objectAtIndex:5];
    
    if (compsNow.year - comps.year > 0) {
        dateStrr = [NSString stringWithFormat:@"%@,%@ %@,%@:%@ %@", yyyy, MM, dd, hh, mm, ampm];
    } else if (compsNow.month - comps.month > 0) {
        dateStrr = [NSString stringWithFormat:@"%@ %@,%@:%@ %@", MM, dd, hh, mm, ampm];
    } else if (compsNow.day - comps.day > 1) {
        dateStrr = [NSString stringWithFormat:@"%@ %@,%@:%@ %@", MM, dd, hh, mm, ampm];
    } else if (compsNow.day - comps.day <= 1) {
        dateStrr = [NSString stringWithFormat:@"%@:%@ %@", hh, mm, ampm];
        if (compsNow.day - comps.day == 1) {
            dateStrr = [@"昨天 " stringByAppendingString:dateStrr];
        }
    } else {
        dateStrr = [NSString stringWithFormat:@"%@ %@,%@:%@ %@", MM, dd, hh, mm, ampm];
    }
    
    return dateStrr;
}
+ (NSString *)xm_getNowTimeStr {
    NSDate *datea = [NSDate dateWithTimeIntervalSinceNow:0];
    NSTimeInterval time = [datea timeIntervalSince1970];
    NSString *timeStampString = [NSString stringWithFormat:@"%.0f", time];
    NSTimeInterval _interval = [timeStampString doubleValue];
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:_interval];
    NSDateFormatter *objDateformat = [[NSDateFormatter alloc] init];
    [objDateformat setDateFormat:@"yyyy-MM-dd"];
    NSString *timeStr = [objDateformat stringFromDate:date];
    return timeStr;
}
//时间戳处理
+ (NSString *)xm_compareCurrentTime:(NSString *)timestamp {
    //将对象类型的时间转换为NSDate类型
    double time = [timestamp doubleValue];
    NSDate *timeDate = [NSDate dateWithTimeIntervalSince1970:time];
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *currentDate = [NSDate date];
    NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:timeDate];
    long temp = 0;
    NSString *result;
    if (timeInterval / 60 < 1) {
        result = @"刚刚";
    } else if ((temp = timeInterval / 60) < 60) {
        result = [NSString stringWithFormat:@"%ld分钟前", temp];
    } else if ((temp = temp / 60) < 24) {
        result = [NSString stringWithFormat:@"%ld小时前", temp];
    } else if ((temp = temp / 24) < 30) {
        result = [NSString stringWithFormat:@"%ld天前", temp];
    } else if ((temp = temp / 30) < 12) {
        result = [NSString stringWithFormat:@"%ld月前", temp];
    } else {
        temp = temp / 12;
        result = [NSString stringWithFormat:@"%ld年前", temp];
    }
    
    return result;
}

+ (NSString *)xm_getTimeFromTimestamp:(NSString *)timestamp {
    //将对象类型的时间转换为NSDate类型
    double time = [timestamp doubleValue];
    NSDate *myDate = [NSDate dateWithTimeIntervalSince1970:time];
    //设置时间格式
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    //    [formatter setDateFormat:@"HH:mm:ss"];
    //将时间转换为字符串
    NSString *timeStr = [formatter stringFromDate:myDate];
    return timeStr;
}

//传入秒 得到 xx:xx:xx
+ (NSString *)xm_getDDHHMMFromSS:(NSString *)totalTime {
    NSInteger seconds = [totalTime integerValue];
    //format of day
    NSString *str_day = [NSString stringWithFormat:@"%02ld", seconds / (3600 * 24)];
    //format of hour
    NSString *str_hour = [NSString stringWithFormat:@"%02ld", seconds / 3600 % 24];
    //format of minute
    NSString *str_minute = [NSString stringWithFormat:@"%02ld", (seconds % 3600) / 60];
    //format of second
    //NSString *str_second = [NSString stringWithFormat:@"%02ld",seconds%60];
    //format of time
    NSString *format_time = [NSString stringWithFormat:@"还剩%@天%@时%@分", str_day, str_hour, str_minute];
    return format_time;
}

- (NSData *)xm_toData {
    return [self dataUsingEncoding:NSUTF8StringEncoding];
}

+ (NSString *)xm_toStringWithData:(NSData *)data {
    if (data && [data isKindOfClass:[NSData class]]) {
        return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    }
    return nil;
}

//递归计算符合规定的文本长度
- (NSString *)xm_cutBeyondTextInLength:(NSInteger)maxLenth {
    size_t length = strlen([self UTF8String]);
    if (length > maxLenth) {
        NSString *text = [self substringToIndex:self.length - 1];
        return [text xm_cutBeyondTextInLength:maxLenth];
    } else {
        return self;
    }
}

- (CGSize)xm_textSizeIn:(CGSize)size font:(UIFont *)font {
    return [self xm_textSizeIn:size font:font breakMode:NSLineBreakByWordWrapping];
}

- (CGSize)xm_textSizeIn:(CGSize)size font:(UIFont *)afont breakMode:(NSLineBreakMode)breakMode {
    return [self xm_textSizeIn:size font:afont breakMode:NSLineBreakByWordWrapping align:NSTextAlignmentLeft];
}

- (CGSize)xm_textSizeIn:(CGSize)size font:(UIFont *)afont breakMode:(NSLineBreakMode)abreakMode align:(NSTextAlignment)alignment {
    NSLineBreakMode breakMode = abreakMode;
    UIFont *font = afont ? afont : [UIFont systemFontOfSize:14];
    
    CGSize contentSize = CGSizeZero;
    
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineBreakMode = breakMode;
    paragraphStyle.alignment = alignment;
    
    NSDictionary *attributes = @{NSFontAttributeName: font, NSParagraphStyleAttributeName: paragraphStyle};
    contentSize = [self boundingRectWithSize:size options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) attributes:attributes context:nil].size;
    contentSize = CGSizeMake((int)contentSize.width + 1, (int)contentSize.height + 1);
    return contentSize;
}

// 在文本中间添加横划线
- (NSMutableAttributedString *)xm_addTextCenterLineWithLineColor:(UIColor *)lineColor {
    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:self];
    [attrString addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlinePatternSolid | NSUnderlineStyleSingle) range:NSMakeRange(0, self.length)];
    [attrString addAttribute:NSStrikethroughColorAttributeName value:lineColor range:NSMakeRange(0, self.length)];
    return attrString;
}

+ (NSString *)xm_stringNoNullWith:(id)sender {
    if (sender == [NSNull null]) { return @""; }
    if ([sender isKindOfClass:[NSNull class]]) { return @""; }
    if (sender == nil) { return @""; }
    if ([sender isEqualToString:@"(null)"]) { return @""; }
    if ([sender isEqualToString:@"nullnull"]) { return @""; }
    return sender;
}

+ (NSString *)xm_getCurrentTime {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSString *dateTime = [formatter stringFromDate:[NSDate date]];
    return dateTime;
}

+ (NSString *)handleUploadText:(NSString *)text {
    if (text.length > 0) {
        return [text stringByReplacingOccurrencesOfString:@"\n+" withString:@"\n" options:NSRegularExpressionSearch range:NSMakeRange(0, text.length)];
    }
    return @"";
}

@end
